﻿using RabbitMQ.Client;

namespace Tszy.Unlimited.Base.Infrastructure.Queues.RabbitMQ;

/// <summary>
/// RabbitMQ 连接创建者。
/// </summary>
public interface IRabbitMQConnectionBuilder : IDisposable
{
    /// <summary>
    /// 生成一个新的 IModel。
    /// </summary>
    /// <returns></returns>
    IModel Build();
}

/// <summary>
/// RabbitMQ 连接创建者。
/// </summary>
public class RabbitMQConnectionBuilder : IRabbitMQConnectionBuilder
{
    private IConnectionFactory _connectionFactory;
    private IModel? _channel;
    private IConnection? _connection;

    /// <summary>
    /// 初始化。
    /// </summary>
    public RabbitMQConnectionBuilder() : this(
        new ConnectionFactory { HostName = "localhost" })
    {
    }

    /// <summary>
    /// 初始化。
    /// </summary>
    /// <param name="hostName">主机名称。</param>
    /// <param name="port">端口号。</param>
    /// <param name="userName">用户名。</param>
    /// <param name="password">密码。</param>
    public RabbitMQConnectionBuilder(string hostName, int port, string userName, string password)
    {
        var connectionFactory = new ConnectionFactory();

        if (string.IsNullOrWhiteSpace(hostName))
        {
            hostName = "localhost";
        }

        connectionFactory.HostName = hostName;

        if (port > 0)
        {
            connectionFactory.Port = port;
        }

        if (!string.IsNullOrWhiteSpace(userName))
        {
            connectionFactory.UserName = userName;
        }

        if (!string.IsNullOrWhiteSpace(password))
        {
            connectionFactory.Password = password;
        }

        _connectionFactory = connectionFactory ?? throw new RabbitMQException("connectionFactory 不可以是 null");
    }

    /// <summary>
    /// 初始化。
    /// </summary>
    /// <param name="connectionFactory">RabbitMQ 连接工厂。</param>
    public RabbitMQConnectionBuilder(IConnectionFactory connectionFactory)
    {
        _connectionFactory = connectionFactory ?? throw new RabbitMQException("connectionFactory 不可以是 null");
    }

    /// <summary>
    /// 生成一个新的 IModel。
    /// </summary>
    /// <returns>IModel。</returns>
    public IModel Build()
    {
        _connection = _connectionFactory.CreateConnection();

        if (_connection == null)
            throw new RabbitMQException("创建 RabbitMQ Connection 失败");

        _channel = _connection.CreateModel();
        //_channel.ExchangeDeclare(_config.ExchangeName, _config.ExchangeType);

        return _channel;
    }

    /// <summary>
    ///
    /// </summary>
    public void Dispose()
    {
        if (_channel != null)
            _channel.Dispose();

        if (_connection != null)
            _connection.Dispose();

        GC.SuppressFinalize(this);
    }
}